package lamma.lab.job;

import static junit.framework.Assert.assertEquals;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

import lamma.lab2.job.AsyncStep;
import lamma.test.helper.FutureHelper;

import org.junit.Test;

/**
 * @author maxcellent
 *
 */
@Deprecated
public class ContextRunnerSharedJobs {

	private static class Job1 {
		
		private String a;
		
		private String b;

		private Future<String> resultFuture;
		
		@SuppressWarnings("unused")
		private String job1Result1;
		
		@SuppressWarnings("unused")
		private String job1Result2;
		
		@SuppressWarnings("unused")
		public Job1(String a, String b) {
			super();
			
			System.out.println("create Job1");
			
			this.a = a;
			this.b = b;
		}
		
		@SuppressWarnings("unused")
		public void unexpectedCall() {
			throw new RuntimeException("not supposed to execute");
		}
		
		@SuppressWarnings("unused")
		@Step(serial=1)
		public AsyncStep fetch() {
			resultFuture = FutureHelper.mockFuture(500, a + b);
			return AsyncStep.Builder.fromFuture(resultFuture);
		}
		
		@SuppressWarnings("unused")
		@Step(serial=2)
		public void compile() throws InterruptedException, ExecutionException {
			job1Result1 = a + b;
			job1Result2 = b + a;
		}
	}

	private static class Job2 {
		
		private String a;
		
		private String b;

		private Future<String> resultFuture;
		
		@SuppressWarnings("unused")
		private String job2result1;
		
		@SuppressWarnings("unused")
		private String job2result2;
		
		@SuppressWarnings("unused")
		private String job2result3;
		
		@SuppressWarnings("unused")
		private String job2result4;
		
		@SuppressWarnings("unused")
		public Job2(String a, String b) {
			super();
			
			System.out.println("create job2");
			
			this.a = a;
			this.b = b;
		}
		
		@SuppressWarnings("unused")
		public void unexpectedCall() {
			throw new RuntimeException("not supposed to execute");
		}
		
		@SuppressWarnings("unused")
		@Step(serial=1)
		public AsyncStep fetch() {
			resultFuture = FutureHelper.mockFuture(1000, a + b + b);
			return AsyncStep.Builder.fromFuture(resultFuture);
		}
		
		@SuppressWarnings("unused")
		@Step(serial=2)
		public void compile() throws InterruptedException, ExecutionException {
			job2result1 = a + a + a;
			job2result2 = a + a + b;
			job2result3 = a + b + b;
			job2result4 = b + b + b;
		}
	}
	
	private class TestContext {
		
		@SuppressWarnings("unused")
		String input1;
		
		@SuppressWarnings("unused")
		String input2;
		
		@SuppressWarnings("unused")
		String input3;
		
		@FeedBy(job=Job1.class, params={"input1", "input2"}, result="job1Result1")
		String job1Result1;
		
		@FeedBy(job=Job1.class, params={"input1", "input2"}, result="job1Result2")
		String job1Result2;
		
		@FeedBy(job=Job2.class, params={"input1", "input3"}, result="job2result1")
		String job2Result1;
		
		@FeedBy(job=Job2.class, params={"input1", "input3"}, result="job2result2")
		String job2Result2;
		
		@FeedBy(job=Job2.class, params={"input1", "input3"}, result="job2result3")
		String job2Result3;
		
		@FeedBy(job=Job2.class, params={"input1", "input3"}, result="job2result4")
		String job2Result4;

		public TestContext(String input1, String input2, String input3) {
			super();
			this.input1 = input1;
			this.input2 = input2;
			this.input3 = input3;
		}
	}

	@Test
	public void test() {
		TestContext c = new TestContext("1", "2", "3");
		
		long start = System.currentTimeMillis();
		
		ContextRunner runner = new ContextRunner();
		runner.run(c);
		
		long end = System.currentTimeMillis();
		System.out.println(end - start);
		
		assertEquals("12", c.job1Result1);
		assertEquals("21", c.job1Result2);
		assertEquals("111", c.job2Result1);
		assertEquals("113", c.job2Result2);
		assertEquals("133", c.job2Result3);
		assertEquals("333", c.job2Result4);
	}
}
